package com.hnust.controller.paper.paperManagement;

import com.hnust.domain.ChoiceQuestion;
import com.hnust.domain.PaperInfoPreview;
import com.hnust.domain.Result;
import com.hnust.fx.FXMLController;
import com.hnust.service.PreviewPaperService;
import com.hnust.service.impl.PreviewPaperServiceImpl;
import com.hnust.util.PaperDataModel;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.geometry.Insets;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.ScrollPane;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import lombok.SneakyThrows;
import javax.swing.*;
import javax.swing.text.Element;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import org.springframework.beans.factory.annotation.Autowired;

import java.awt.*;
import java.io.FileNotFoundException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.ResourceBundle;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@FXMLController
public class PaperPreviewController implements Initializable  {

    @Autowired
    private PreviewPaperService previewPaperService;
    @FXML
    public Button generatePaper;
    @FXML
    public ScrollPane container;
    @FXML
    public AnchorPane contain;

    //考试名称
    @FXML
    public Label headTitle;
    @FXML
    public VBox choiceQues,judgmentQuestion,fillQuestion,shortAnswerQuestion;
    @FXML
    public ScrollPane choiceQuestionScrollPane,judgmentQuestionScrollPane,fillQuestionScrollPane,shortAnswerQuestionScrollPane;
    @FXML
    public ScrollPane choiceAnsQuestionScrollPane,judgmentAnsQuestionScrollPane,fillAnsQuestionScrollPane,shortAnsQuestionScrollPane;
    @FXML
    public VBox choiceQuestionVBoxs;
    @FXML
    public VBox judgmentQuestionVBoxs;
    @FXML
    public VBox fillQuestionVBoxs;
    @FXML
    public VBox shortAnswerQuestionVBoxs;
    @FXML
    public VBox choiceAnsQuestionVBoxs;
    @FXML
    public VBox judgmentAnsQuestionVBoxs;
    @FXML
    public VBox fillAnsQuestionVBoxs;
    @FXML
    public VBox shortAnsQuestionVBoxs;

    public static PaperDataModel model = new PaperDataModel();
    public static String PaperId; //从PaperList传来的试卷ID
    private Pattern pattern1,pattern2;
    private ArrayList<ChoiceQuestion> choiceQuestions; //存放需要显示的数据(选择题数据的初始状态)
    private ArrayList<String> fillQuestions;//存放需要显示的数据(填空题数据的初始状态)
    private ArrayList<String> choiceQuesAns;//选择题答案
    private ArrayList<String> choiceQuesAnalyse;//选择题答案解析
    @SneakyThrows
    @Override
    public void initialize(URL location, ResourceBundle resources){
        listenChange();
        PaperId=model.getText();
        model.textProperty().addListener((obs, oldText, newText) -> {
            PaperId=newText;
            System.out.println("预览页面PaperId="+PaperId);
        });
        //考试名称---需要动态赋值---请求
        headTitle.setText("2020-2021 (2) 学年操作系统期末考试");//获取并设置考试名称
        //是否可以用鼠标移动
        container.setPannable(true);
        //使container的内容适应根据窗口大小自动调整
        container.setFitToWidth(true);
        container.setFitToHeight(true);
        choiceQuestionScrollPane.setHbarPolicy(ScrollPane.ScrollBarPolicy.NEVER);
        judgmentQuestionScrollPane.setHbarPolicy(ScrollPane.ScrollBarPolicy.NEVER);
        fillQuestionScrollPane.setHbarPolicy(ScrollPane.ScrollBarPolicy.NEVER);
        shortAnswerQuestionScrollPane.setHbarPolicy(ScrollPane.ScrollBarPolicy.NEVER);
        choiceAnsQuestionScrollPane.setHbarPolicy(ScrollPane.ScrollBarPolicy.NEVER);
        judgmentAnsQuestionScrollPane.setHbarPolicy(ScrollPane.ScrollBarPolicy.NEVER);
        fillAnsQuestionScrollPane.setHbarPolicy(ScrollPane.ScrollBarPolicy.NEVER);
        shortAnsQuestionScrollPane.setHbarPolicy(ScrollPane.ScrollBarPolicy.NEVER);
        pattern1=Pattern.compile("&nbsp");
        pattern2=Pattern.compile("<p>|</p>");

        choiceQuestions=new ArrayList<>();
        fillQuestions=new ArrayList<>();
        choiceQuesAns=new ArrayList<>();
        choiceQuesAnalyse=new ArrayList<>();
        String fillQues1="<p>如果信号量的当前值为-4,则表示系统中在该信号量上有（&nbsp&nbsp&nbsp&nbsp）个等待进程。</p>";
        String fillQues2="<p>某系统中共有&nbsp10&nbsp台磁带机被&nbspm&nbsp个进程竞争，&nbsp每个进程最多要求&nbsp3&nbsp台磁带机，那么当&nbspm&nbsp的取值为(&nbsp&nbsp)时，系统不会发生死锁。</p>";
        String fillQues3="<p>什么是操作系统?它的主要功能是什么?</p>";
        fillQuestions.add(fillQues1);
        fillQuestions.add(fillQues2);
        fillQuestions.add(fillQues3);
        String choiceAns1="<p>D</p>";
        String choiceAnalyse="<p>在存储管理中常用(&nbsp&nbsp)方式来摆脱主存容量的限制。</p><p>在存储管理中常用(&nbsp&nbsp)方式来摆脱主存容量的限制。" +
                "<p>在存储管理中常用(&nbsp&nbsp)方式来摆脱主存容量的限制。</p><p>在存储管理中常用(&nbsp&nbsp)方式来摆脱主存容量的限制。</p>" +
                "<p>在存储管理中常用(&nbsp&nbsp)方式来摆脱主存容量的限制。</p><p>在存储管理中常用(&nbsp&nbsp)方式来摆脱主存容量的限制。</p>" +
                "</p><p>在存储管理中常用(&nbsp&nbsp)方式来摆脱主存容量的限制。</p><p>在存储管理中常用(&nbsp&nbsp)方式来摆脱主存容量的限制。</p>";
        choiceQuesAns.add(choiceAns1);
        choiceQuesAnalyse.add(choiceAnalyse);
        String shortQuestion1="<p>设单&nbspCPU&nbsp环境下，&nbsp有三道作业，&nbsp它们的提交时间及运行时间如下表：" +
                "</p><p><img style=\"width: 640.50px;height: 157.05px;\" src=\"http://47.110.133.95:8001/pic/1025412295.png\"/>" +
                "</p><p>若采用短作业优先调度策略，&nbsp作业单道串行运行时的调度次序为(&nbsp)，&nbsp平均周转时间=(&nbsp)。</p>";
        ArrayList<String> shortQuestion=new ArrayList<>();
        shortQuestion.add(shortQuestion1);

        ArrayList<String> temp=null;
        showChoiceQues();//显示试卷选择题
        showFillOrJugeQues(fillQuestions,fillQuestionVBoxs);  //显示试卷填空题
        showFillOrJugeQues(fillQuestions,judgmentQuestionVBoxs); //显示试卷判断题
        showAnswerQuesModel(shortQuestion,shortAnswerQuestionVBoxs,temp);//显示试卷简答题，此处借用了填空题的题目
        showAnswerQuesModel(choiceQuesAns,choiceAnsQuestionVBoxs,choiceQuesAnalyse);//显示选择题答案
        showAnswerQuesModel(choiceQuesAns,judgmentAnsQuestionVBoxs,choiceQuesAnalyse);//显示判断题答案，此处借用了选择题的答案
        showAnswerQuesModel(choiceQuesAns,fillAnsQuestionVBoxs,choiceQuesAnalyse);//显示填空题答案，此处借用了选择题的答案
        showAnswerQuesModel(choiceQuesAns,shortAnsQuestionVBoxs,choiceQuesAnalyse);//显示简答题答案，此处借用了选择题的答案


//        previewPaperService.getPaperInfo("101157");
        Result<List<PaperInfoPreview>> res=previewPaperService.getPaperInfo("13423");
        System.out.println("res="+res);
    }

    public static void setText(String text)
    {
        model.setText(text);
    }

    public void listenChange(){
        //通过监听最外层容器的宽度，来改变内层Anchor的宽度
        container.widthProperty().addListener(new ChangeListener<Number>() {
            @Override
            public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) {
                contain.setPrefWidth((double)newValue-2);
            }
        });
        //通过监听最外层容器的高度，来改变内层Anchor的高度
        container.heightProperty().addListener(new ChangeListener<Number>() {
            @Override
            public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) {
                contain.setPrefHeight((double)newValue-2);
            }
        });
    }

    public void showChoiceQues(){
        //两个选择题假数据,并将它们显示到id=choiceQuestionScrollPane的区域中
        ChoiceQuestion chQust1=new ChoiceQuestion(
                "2","<p>CPU&nbsp输出数据的速度远远高于打印机的打印速度，为解决这一矛盾，&nbsp可采用（&nbsp）</p>",
                "<p>D.覆盖技术</p>","<p>A.打印技术</p>","<p>B.填充技术</p>","<p>C.删除技术</p>","<p>D.覆盖技术</p>",
                2,"考察输出数据的速度与外设之间的匹配关系");
        ChoiceQuestion chQust2=new ChoiceQuestion(
                "2","<p>通过操作系统对外围设备的管理实现了“设备处理的一致性”。&nbsp这种“一致性”&nbsp是指（&nbsp&nbsp）</p>",
                "<p>C.通道程序设计的处理一致性</p>","<p>A.通道物理设计的处理一致性</p>","<p>B.它们之间毫无关系</p>","<p>C.通道程序设计的处理一致性</p>","<p>D.只要提高外设处理速度即可</p>",
                2,"考察输出数据的速度与外设之间的匹配关系");
        ChoiceQuestion chQust3=new ChoiceQuestion(
                "2","<p>通过操作系统对外围设备的管理实现了“设备处理的一致性”。&nbsp这种“一致性”&nbsp是指（&nbsp&nbsp）</p>",
                "<p>C.通道程序设计的处理一致性</p>","<p>A.通道物理设计的处理一致性</p>","<p>B.它们之间毫无关系</p>","<p>C.通道程序设计的处理一致性</p>","<p>D.只要提高外设处理速度即可</p>",
                2,"考察输出数据的速度与外设之间的匹配关系");
        choiceQuestions.add(chQust1);
        choiceQuestions.add(chQust2);
        choiceQuestions.add(chQust3);
        //它这些数据放到vBox中，再加入到choiceQuestionVBoxs区域中显示
        for (int i=0;i<choiceQuestions.size();i++){
            VBox vBox=new VBox(); //存放整个题目的数据
            HBox hBox=new HBox(); //存放题目和右边的修改按钮
            VBox vBox_answers=new VBox();//存放答案选项
            HBox hBox_btns=new HBox();
            String ques=choiceQuestions.get(i).getQuestion();
            Matcher matcher1=pattern1.matcher(ques);
            String ques1=matcher1.replaceAll(" ").trim();
            Matcher matcher2=pattern2.matcher(ques1);
            String question=matcher2.replaceAll("").trim();
            //去除<>标签内容
            question=question.replaceAll("\\<.*?>","");
            question=(i+1)+"."+question;
            Label question_label=new Label(question);
            question_label.setWrapText(true);
            question_label.setPrefWidth(700);
            ImageIcon image=new ImageIcon("resources/image/detail.png");
            Label detail_btn=new Label("详情");
            detail_btn.setId("detail_btn");
            Label edit_btn=new Label("编辑");
            Label del_btn=new Label("删除");
            //设置选项
            String AnswerA1=choiceQuestions.get(i).getAnswerA();
            Matcher matcherA1=pattern1.matcher(AnswerA1);
            String AnswerA2=matcherA1.replaceAll(" ").trim();
            Matcher matcherA2=pattern2.matcher(AnswerA2);
            String AnswerA=matcherA2.replaceAll("").trim();
            //去除<>标签内容
            AnswerA=AnswerA.replaceAll("\\<.*?>","");

            String AnswerB1=choiceQuestions.get(i).getAnswerB();
            Matcher matcherB1=pattern1.matcher(AnswerB1);
            String AnswerB2=matcherB1.replaceAll(" ").trim();
            Matcher matcherB2=pattern2.matcher(AnswerB2);
            String AnswerB=matcherB2.replaceAll("").trim();
            //去除<>标签内容
            AnswerB=AnswerB.replaceAll("\\<.*?>","");

            String AnswerC1=choiceQuestions.get(i).getAnswerC();
            Matcher matcherC1=pattern1.matcher(AnswerC1);
            String AnswerC2=matcherC1.replaceAll(" ").trim();
            Matcher matcherC2=pattern2.matcher(AnswerC2);
            String AnswerC=matcherC2.replaceAll("").trim();
            //去除<>标签内容
            AnswerC=AnswerC.replaceAll("\\<.*?>","");

            String AnswerD1=choiceQuestions.get(i).getAnswerD();
            Matcher matcherD1=pattern1.matcher(AnswerD1);
            String AnswerD2=matcherD1.replaceAll(" ").trim();
            Matcher matcherD2=pattern2.matcher(AnswerD2);
            String AnswerD=matcherD2.replaceAll("").trim();
            //去除<>标签内容
            AnswerD=AnswerD.replaceAll("\\<.*?>","");

            Label answerA =new Label(AnswerA);
            Label answerB =new Label(AnswerB);
            Label answerC =new Label(AnswerC);
            Label answerD =new Label(AnswerD);
            vBox_answers.getChildren().add(answerA);
            vBox_answers.getChildren().add(answerB);
            vBox_answers.getChildren().add(answerC);
            vBox_answers.getChildren().add(answerD);
            vBox_answers.setPadding(new Insets(0,10,10,60));

            hBox.getChildren().add(question_label);
            hBox_btns.getChildren().add(detail_btn);
            hBox_btns.getChildren().add(edit_btn);
            hBox_btns.getChildren().add(del_btn);
            hBox_btns.setStyle("-fx-alignment: right;-fx-spacing: 10px");
            hBox_btns.setPadding(new Insets(6,50,10,580));
            hBox.getChildren().add(hBox_btns);
            hBox.setPadding(new Insets(20,0,10,30));
            vBox.getChildren().add(hBox);
            vBox.getChildren().add(vBox_answers);
            choiceQuestionVBoxs.getChildren().add(vBox);
        }
    }
    public void showFillOrJugeQues(ArrayList<String> questions,VBox QuestionVBoxs){
            //这些数据放到vBox中，再加入到fillQuestionVBoxs区域中显示
            for (int i=0;i<questions.size();i++){
                VBox vBox=new VBox(); //存放整个题目的数据
                HBox hBox=new HBox(); //存放题目和右边的修改按钮
                String ques1=questions.get(i);
                Matcher matcher1=pattern1.matcher(ques1);
                String ques2=matcher1.replaceAll(" ").trim();
                Matcher matcher2=pattern2.matcher(ques2);
                String ques=matcher2.replaceAll("").trim();
                //去除<>标签内容
                ques=ques.replaceAll("\\<.*?>","");
                String question=(i+1)+"."+ques;
                Label fillQuestion=new Label(question);//存放处理后的填空题题目
                fillQuestion.setWrapText(true);
                fillQuestion.setStyle("-fx-pref-width: 1200px;");
                //右边三个按钮
                Label detail_btn=new Label("详情");
                Label edit_btn=new Label("编辑");
                Label del_btn=new Label("删除");
                //装入右边的三个按钮
                HBox hBox_btns=new HBox();
                hBox_btns.getChildren().add(detail_btn);
                hBox_btns.getChildren().add(edit_btn);
                hBox_btns.getChildren().add(del_btn);
                hBox_btns.setStyle("-fx-alignment: right;-fx-spacing: 10px");
                hBox_btns.setPadding(new Insets(3,30,10,50));
                hBox.getChildren().add(fillQuestion);
                hBox.getChildren().add(hBox_btns);
                hBox.setPadding(new Insets(20,0,10,30));
                hBox.setStyle("-fx-pref-width: 1490px;-fx-spacing: 10px");
                vBox.getChildren().add(hBox);
                QuestionVBoxs.getChildren().add(vBox);
            }
    }

    /**
     * 用来显示试卷预览的简答题以及试卷答案的各个模块显示
     * @param questions 要显示的内容：题目或者答案
     * @param QuestionVBoxs 要显示的区域
     * @param analyse 显示框里的数据：默认为"请在此区域作答",否则显示答案解析
     */
    public void showAnswerQuesModel(ArrayList<String> questions,VBox QuestionVBoxs,ArrayList<String> analyse) throws FileNotFoundException {
        //这些数据放到vBox中，再加入到fillQuestionVBoxs区域中显示
        for (int i=0;i<questions.size();i++) {
            VBox vBox = new VBox(); //存放整个题目的数据
            HBox hBox = new HBox(); //存放题目和右边的修改按钮
            String ques1 = questions.get(i);
            Matcher matcher1 = pattern1.matcher(ques1);
            String ques2 = matcher1.replaceAll(" ").trim();
            Matcher matcher2 = pattern2.matcher(ques2);
            String ques = matcher2.replaceAll("").trim();
            //获取题目数据中的图片地址
            List<String> img_urls=RegExp(ques);
            ImageIcon icon=new ImageIcon();
            VBox imgs_vbox=new VBox();
            imgs_vbox.setPadding(new Insets(5,10,5,40));
            List<ImageView> imageViews=new ArrayList<ImageView>(img_urls.size());
            for (int j=0;j<img_urls.size();j++){
                javafx.scene.image.Image image = new javafx.scene.image.Image(img_urls.get(j), 800, 200, false, false);
                javafx.scene.image.ImageView imageView=new ImageView();
                imageView.setImage(image);
                imageViews.add(imageView);
            }
            //去除<>标签内容
            ques=ques.replaceAll("\\<.*?>","");
            String question = (i + 1) + "." + ques;
            String anal="";
            if (analyse != null) {
                String anal1 = analyse.get(i);
                Matcher matcher3 = pattern1.matcher(anal1);
                String anal2 = matcher3.replaceAll(" ").trim();
                Matcher matcher4 = pattern2.matcher(anal2);
                anal = matcher4.replaceAll("").trim();
            }
            Label fillQuestion = new Label(question);//存放处理后的填空题题目
            fillQuestion.setWrapText(true);
            fillQuestion.setStyle("-fx-pref-width: 1200px;");
            //右边三个按钮
            Label detail_btn = new Label("详情");
            Label edit_btn = new Label("编辑");
            Label del_btn = new Label("删除");
            //创建简答题的答题框，并设置样式
            VBox rec_vbox=new VBox();
            //答案解析标签
            Label answerRec=new Label();
            answerRec.setWrapText(true);
            answerRec.setPadding(new Insets(5,20,10,20));
            answerRec.setStyle("-fx-pre-width: 1100px;-fx-min-height: 80px;-fx-max-width:1100px;" +
                                "-fx-border-width: 0.5;-fx-border-color: #696969;" +
                                "-fx-border-radius: 7");
            rec_vbox.setPadding(new Insets(5,10,10,40));
            //设置矩形框里的数据
            if (analyse==null){
                answerRec.setText("请在此区域作答");
            }
            else if (analyse!=null){
                if (anal.equals("")){
                    answerRec.setText("解析：略");
                }
                else{
                    answerRec.setText("解析："+anal);
                }
            }

            rec_vbox.getChildren().add(answerRec);
            //装入右边的三个按钮
            HBox hBox_btns = new HBox();
            hBox_btns.getChildren().add(detail_btn);
            hBox_btns.getChildren().add(edit_btn);
            hBox_btns.getChildren().add(del_btn);
            hBox_btns.setStyle("-fx-alignment: right;-fx-spacing: 10px");
            hBox_btns.setPadding(new Insets(3, 30, 10, 50));
            hBox.getChildren().add(fillQuestion);
            hBox.getChildren().add(hBox_btns);
            hBox.setPadding(new Insets(20, 20, 10, 35));
            hBox.setStyle("-fx-pref-width: 1490px;-fx-spacing: 10px");
            vBox.getChildren().add(hBox);
            for (int j=0;j<imageViews.size();j++){
                imgs_vbox.getChildren().add(imageViews.get(j));
            }
            vBox.getChildren().add(imgs_vbox);
            vBox.getChildren().add(rec_vbox);
            QuestionVBoxs.getChildren().add(vBox);
        }
    }

    /**
     * 获取题目里的图片的src
     * @param str
     * @return
     */
    public List<String> RegExp(String str){
        List<String> srcList = new ArrayList<String>(); //用来存储获取到的图片地址
        Pattern p = Pattern.compile("<(img|IMG)(.*?)(>|></img>|/>)");//匹配字符串中的img标签
        Matcher matcher = p.matcher(str);
        boolean hasPic = matcher.find();
        if(hasPic == true)//判断是否含有图片
        {
            while(hasPic) //如果含有图片，那么持续进行查找，直到匹配不到
            {
                String group = matcher.group(2);//获取第二个分组的内容，也就是 (.*?)匹配到的
                Pattern srcText = Pattern.compile("(src|SRC)=(\"|\')(.*?)(\"|\')");//匹配图片的地址
                Matcher matcher2 = srcText.matcher(group);
                if( matcher2.find() )
                {
                    srcList.add( matcher2.group(3) );//把获取到的图片地址添加到列表中
                }
                hasPic = matcher.find();//判断是否还有img标签
            }

        }
        return srcList;
    }

}
